package com.example.hrandroidapp.common;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class DateUtils {

	public static final String DATE_DDMMMMM_FORMAT = "dd MMMM";
    public static final String DATE_DDMMYYYY_FORMAT = "dd-MM-yyyy";
    public static final String DATE_YYYYMMDD_FORMAT = "yyyy-MM-dd";
    public static final String DATE_DDMMMYYYY_FORMAT = "dd-MMM-yyyy";
    public static final String DATE_YYYYMMDDHHMMSS_FORMAT = "yyyy-MM-dd HH:mm:ss";
	public static final String DATE_DDMMM_HHMM_FORMAT = "dd-MMM HH:mm:ss";
	public static final String DATE_HHMM_FORMAT = "HH:mm";
	public static final String DATE_DDMMM_FORMAT = "dd-MMM";
	public static final String DATE_MMMDD_FORMAT = "MMM-dd";
	public static final String DATE_DDMMMYY_HHMM_FORMAT = "dd MMM yy HH:mm";
	public static final String DATE_DDMMYY_HHMMSS_FORMAT = "dd-MM-yy HH:mm:ss";
	public static final String DATE_DDMMMYYYY_HHMM_FORMAT = "dd MMM yyyy HH:mm";	
	public static final String DATE_DDMMMYYYY_BEAK_HHMMSS_FORMAT = "dd MMM yyyy\nHH:mm:ss";
	
	private static final double ONE_DAY = 24*60*60*1000L; //in ms
	
	
	private static Map<Integer, String> DAY_OF_WEEK_SHORT_LABEL_MAP = new HashMap<Integer, String>();
	
	static {
		
		DAY_OF_WEEK_SHORT_LABEL_MAP.put(Calendar.SUNDAY, "Sun");
		DAY_OF_WEEK_SHORT_LABEL_MAP.put(Calendar.MONDAY, "Mon");
		DAY_OF_WEEK_SHORT_LABEL_MAP.put(Calendar.TUESDAY, "Tue");
		DAY_OF_WEEK_SHORT_LABEL_MAP.put(Calendar.WEDNESDAY, "Wed");
		DAY_OF_WEEK_SHORT_LABEL_MAP.put(Calendar.THURSDAY, "Thu");
		DAY_OF_WEEK_SHORT_LABEL_MAP.put(Calendar.FRIDAY, "Fri");
		DAY_OF_WEEK_SHORT_LABEL_MAP.put(Calendar.SATURDAY, "Sat");
	}
	
	
	
	private static Map<Integer, String> MONTH_LONG_LABEL_MAP = new HashMap<Integer, String>();
	
	static {
		MONTH_LONG_LABEL_MAP.put(Calendar.JANUARY, "January");
		MONTH_LONG_LABEL_MAP.put(Calendar.FEBRUARY, "February");
		MONTH_LONG_LABEL_MAP.put(Calendar.MARCH, "March");
		MONTH_LONG_LABEL_MAP.put(Calendar.APRIL, "April");
		MONTH_LONG_LABEL_MAP.put(Calendar.MAY, "May");
		MONTH_LONG_LABEL_MAP.put(Calendar.JUNE, "June");
		MONTH_LONG_LABEL_MAP.put(Calendar.JULY, "July");
		MONTH_LONG_LABEL_MAP.put(Calendar.AUGUST, "August");
		MONTH_LONG_LABEL_MAP.put(Calendar.SEPTEMBER, "September");
		MONTH_LONG_LABEL_MAP.put(Calendar.OCTOBER, "October");
		MONTH_LONG_LABEL_MAP.put(Calendar.NOVEMBER, "November");
		MONTH_LONG_LABEL_MAP.put(Calendar.DECEMBER, "December");
	}

private static Map<Integer, String> MONTH_SHORT_LABEL_MAP = new HashMap<Integer, String>();
	
	static {
		MONTH_SHORT_LABEL_MAP.put(Calendar.JANUARY, "Jan");
		MONTH_SHORT_LABEL_MAP.put(Calendar.FEBRUARY, "Feb");
		MONTH_SHORT_LABEL_MAP.put(Calendar.MARCH, "Mar");
		MONTH_SHORT_LABEL_MAP.put(Calendar.APRIL, "Apr");
		MONTH_SHORT_LABEL_MAP.put(Calendar.MAY, "May");
		MONTH_SHORT_LABEL_MAP.put(Calendar.JUNE, "Jun");
		MONTH_SHORT_LABEL_MAP.put(Calendar.JULY, "Jul");
		MONTH_SHORT_LABEL_MAP.put(Calendar.AUGUST, "Aug");
		MONTH_SHORT_LABEL_MAP.put(Calendar.SEPTEMBER, "Sep");
		MONTH_SHORT_LABEL_MAP.put(Calendar.OCTOBER, "Oct");
		MONTH_SHORT_LABEL_MAP.put(Calendar.NOVEMBER, "Nov");
		MONTH_SHORT_LABEL_MAP.put(Calendar.DECEMBER, "Dec");
	}
	
	public static String getCurrentTime() {
		  SimpleDateFormat formatter = new SimpleDateFormat(DATE_HHMM_FORMAT);
	        return formatter.format(new Date());
	}
	
	
    public static Date convert(String inputDate, String inputFormat) {
        SimpleDateFormat formatter = new SimpleDateFormat(inputFormat);
        Date result = null;
        if(inputDate.contains("+")) {
        	inputDate = inputDate.substring(0, 10);
        	inputDate.replace("-", "/");
        }
        try {
            result = formatter.parse(inputDate);
        } catch (ParseException e) {}
        return result;
    }

    public static String convert(Date input, String outputFormat) {
        SimpleDateFormat formatter = new SimpleDateFormat(outputFormat);
        return formatter.format(input);
    }
    
    public static Date convert(Integer value, String outputFormat) {
    	SimpleDateFormat originalFormat = new SimpleDateFormat("yyyyMMdd");
    	Date date = new Date();
		try {
			date = originalFormat.parse(value.toString());
		} catch (ParseException e) {
			HRLog.postLogErr(e.getLocalizedMessage(), " at DateUtil.convert(int, string)");
			e.printStackTrace(); 
		}
    	return date;
    }

    public static Date getJavaDate(String date) {
    	Date creDate = new Date(Integer.parseInt(date.substring(0, 4)), 
        		Integer.parseInt(date.substring(4, 6)) - 1, 
        		Integer.parseInt(date.substring(6, 8)),
        		Integer.parseInt(date.substring(8,10)),
        		Integer.parseInt(date.substring(10, 12)),
        		Integer.parseInt(date.substring(12, 14)));
    	
    	return creDate;
    }
    
    public static String getMMMddFormat(String date) {
    	Date creDate = new Date(Integer.parseInt(date.substring(0, 4)), 
        		Integer.parseInt(date.substring(4, 6)) - 1, 
        		Integer.parseInt(date.substring(6, 8)));
        return DateUtils.convert(creDate, DateUtils.DATE_MMMDD_FORMAT);
    }
    
	public static Date getSysdateWithoutTime() {
		Calendar today = Calendar.getInstance();
		today.set(Calendar.HOUR, 0);
		today.set(Calendar.MINUTE, 0);
		today.set(Calendar.SECOND, 0);
		today.set(Calendar.AM_PM, Calendar.AM);
		today.set(Calendar.MILLISECOND, 0);
		return today.getTime();
	}
	
	public static Date addDay(Date refDate, int amt) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(refDate);
		cal.add(Calendar.DAY_OF_MONTH, amt);
		
		return cal.getTime();
	}
	
	public static Date addHour(Date refDate, int amt) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(refDate);
		cal.add(Calendar.HOUR, amt);
		
		return cal.getTime();
	}
	
	public static Date addMinute(Date refDate, int amt) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(refDate);
		cal.add(Calendar.MINUTE, amt);
		
		return cal.getTime();
	}

	public static int getYear(Date date) {
		Calendar temp = Calendar.getInstance();
		temp.setTime(date);
		
		return temp.get(Calendar.YEAR);
	}
	public static int getMonth(Date date) {
		Calendar temp = Calendar.getInstance();
		temp.setTime(date);
		
		return temp.get(Calendar.MONTH);
	}
	public static int getDay(Date date) {
		Calendar temp = Calendar.getInstance();
		temp.setTime(date);
		
		return temp.get(Calendar.DATE);
	}
	
	public static int getHour(Date date) {
		Calendar temp = Calendar.getInstance();
		temp.setTime(date);
		
		return temp.get(Calendar.HOUR_OF_DAY);
	}
	
	public static int getMinutes(Date date) {
		Calendar temp = Calendar.getInstance();
		temp.setTime(date);
		
		return temp.get(Calendar.MINUTE);
	}
	
//	public static double differenceInDays(Date from, Date to) {
//		
//		return (to.getTime() - from.getTime())/ONE_DAY;
//	}
	
    public static int differenceInDays(Calendar startDate, Calendar endDate) {
    	startDate = removeTime(startDate);
    	endDate = removeTime(endDate);
        Calendar date = (Calendar) startDate.clone();
        int daysBetween = 0;
        while (date.before(endDate)) {
            date.add(Calendar.DAY_OF_MONTH, 1);
            daysBetween++;
        }
        return daysBetween;
    }
    
    
    public static Calendar removeTime(Calendar cal)
    {
    	cal.set(Calendar.HOUR_OF_DAY, 0);
    	cal.set(Calendar.MINUTE, 0);
    	cal.set(Calendar.SECOND, 0);
    	cal.set(Calendar.MILLISECOND, 0);
    	
    	return cal;
    }
    
    
	/**
	 * Returns a date that is added by the amount specified to the refDate
	 * 
	 * @param refDate date for which amount to add
	 * @param calendarType Calendar.MONTH, Calendar.DATE, Calendar.YEAR
	 * @param amt number of units to add
	 * @return
	 */	
	public static Date add(Date refDate, int calendarType, int amt) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(refDate);
		cal.add(calendarType, amt);
		
		return cal.getTime();
	}
	
	
	public static int getDayOfWeek(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.DAY_OF_WEEK);
	}
	
	public static String getDayOfWeekShortLabel(Integer dayOfWeek) {
		return DAY_OF_WEEK_SHORT_LABEL_MAP.get(dayOfWeek);
	}
	
	
	public static Integer getMonthLongInteger(String month) {
		
		Set<Integer> keys = MONTH_LONG_LABEL_MAP.keySet();
		for (Iterator< Integer> it = keys.iterator(); it.hasNext();)
		{
			Integer key = it.next();
			if(getMonthLongLabel(key).equals(month))
				return key;
		}
		
		return 0;
	}
	
	public static String getMonthLongLabel(Integer month) {
		return MONTH_LONG_LABEL_MAP.get(month);
	}
	
	public static String getMonthShortLabel(Integer month) {
		return MONTH_SHORT_LABEL_MAP.get(month);
	}
	
	
	
	public static void toLastDayOfMonth(Date date)
	{
		Calendar dateCleared =  Calendar.getInstance();
		dateCleared.clear();		
		dateCleared.set(getYear(date),getMonth(date), 1);
		dateCleared.add(Calendar.MONTH, 1);
		dateCleared.add(Calendar.DAY_OF_MONTH, -1);		
		date.setTime(dateCleared.getTimeInMillis());
	}
	
	public static String getDateInString(int year, int month, int day, String format) {
		String returnFormat = null;
		
		String strMonth = (month < 10)? "0" + month : String.valueOf(month);
		String strDay = (day < 10)? "0" + day : String.valueOf(day);
		if(format.equals(DATE_YYYYMMDD_FORMAT)) {
			returnFormat = year + "-" + strMonth + "-" + strDay;
		}else if(format.equals(DATE_DDMMYYYY_FORMAT)) {
			returnFormat = strDay + "-" + strMonth + "-" + year;
		}
		
		return returnFormat;
	}
	
	public static String getHourMinInString(int hour, int min) {
		String strHr = (hour < 10)? "0" + hour : String.valueOf(hour);
		String strMin = (min < 10)? "0" + min : String.valueOf(min);
		return strHr + ":" + strMin;
	}
	
	public static Date setHourMinSec(Date date, int hr, int min, int sec, int msec) {

		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		 
		// Set time fields to zero
		cal.set(Calendar.HOUR_OF_DAY, hr);
		cal.set(Calendar.MINUTE, min);
		cal.set(Calendar.SECOND, sec);
		cal.set(Calendar.MILLISECOND, msec);
		
		return cal.getTime();
	}
	
}
